package com.hr.classes.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hr.classes.entity.TbClasses;
import com.hr.classes.entity.TbClassesRule;
import com.hr.classes.entity.TbClassesUser;
import com.hr.classes.entity.base.TableListDTO;
import com.hr.classes.entity.dto.TbClassesDTO;
import com.hr.classes.entity.po.TbClassesPO;
import com.hr.classes.entity.vo.TbClassesVO;
import com.hr.classes.mapper.TbClassesMapper;
import com.hr.classes.mapper.TbClassesRuleMapper;
import com.hr.classes.mapper.TbClassesUserMapper;
import com.hr.classes.service.TbClassesService;
import com.hr.system.entity.SysUser;
import com.hr.system.mapper.SysUserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <pre>
 * 描述：TODO
 * </pre>
 *
 * @类名：com.hr.classes.service.impl.TbClassesServiceImpl
 * @创建日期: 2024/5/6 17:35
 */
@Service
public class TbClassesServiceImpl implements TbClassesService {

    @Autowired
    private TbClassesMapper tbClassesMapper;

    @Autowired
    private TbClassesUserMapper tbClassesUserMapper;

    @Autowired
    private TbClassesRuleMapper tbClassesRuleMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public TableListDTO<TbClassesDTO> getList(TbClassesVO tbClassesVO) {
        List<TbClassesDTO> list = new ArrayList<>();

        LambdaQueryWrapper<TbClasses> wrapper = Wrappers.<TbClasses>lambdaQuery()
                .like(StringUtils.isNotBlank(tbClassesVO.getName()), TbClasses::getName, tbClassesVO.getName())
                .eq(StringUtils.isNotBlank(tbClassesVO.getType()), TbClasses::getType, tbClassesVO.getType());
        Integer count = tbClassesMapper.selectCount(wrapper);

        if (count > 0) {
            if (tbClassesVO.getPageNum() != null && tbClassesVO.getPageSize() != null) {
                PageHelper.startPage(tbClassesVO.getPageNum(), tbClassesVO.getPageSize());
            }
            List<TbClasses> tbClassesList = tbClassesMapper.selectList(wrapper);

            TbClassesDTO tbClassesDTO = null;
            for (TbClasses classes : tbClassesList) {
                tbClassesDTO = new TbClassesDTO();
                BeanUtils.copyProperties(classes, tbClassesDTO);

                String attendanceTimeDescription = null;
                if ("1".equals(classes.getType())) {
                    attendanceTimeDescription = "上午" + getDateStr(classes.getMorningWUp()) + "-" + getDateStr(classes.getMorningWDown()) + "\n" +
                            "下午" + getDateStr(classes.getAfternoonWUp()) + "-" + getDateStr(classes.getAfternoonWDown());
                } else if ("2".equals(classes.getType())) {
                    BigDecimal flexTime = Optional.ofNullable(classes.getFlexTime()).orElse(BigDecimal.ZERO);

                    attendanceTimeDescription = "弹性工作" + flexTime.setScale(1, RoundingMode.HALF_UP).toPlainString() + "小时";
                }
                tbClassesDTO.setAttendanceTimeDescription(attendanceTimeDescription);

                // 查询中间表对应的用户id
                List<Integer> classesIds = tbClassesList.stream().map(TbClasses::getId).collect(Collectors.toList());
                LambdaQueryWrapper<TbClassesUser> queryWrapper = Wrappers.<TbClassesUser>lambdaQuery()
                        .eq(true, TbClassesUser::getClassesId, tbClassesDTO.getId());
                List<TbClassesUser> tbClassesUsers = tbClassesUserMapper.selectList(queryWrapper);

                if (!CollectionUtils.isEmpty(tbClassesUsers)) {
                    List<Integer> userIds = tbClassesUsers.stream().map(TbClassesUser::getUserId).collect(Collectors.toList());
                    List<SysUser> sysUsers = sysUserMapper.selectBatchIds(userIds);
                    tbClassesDTO.setSysUsers(sysUsers);
                }

                LambdaQueryWrapper<TbClassesRule> ruleLambdaQueryWrapper = Wrappers.<TbClassesRule>lambdaQuery()
                        .eq(true, TbClassesRule::getClassesId, tbClassesDTO.getId());
                TbClassesRule tbClassesRule = tbClassesRuleMapper.selectOne(ruleLambdaQueryWrapper);
                if (tbClassesRule != null) {
                    Integer ruleId = tbClassesRule.getRuleId();
                    tbClassesDTO.setTbAttendanceRules(ruleId);
                }

                list.add(tbClassesDTO);
            }
        }
        PageInfo<TbClassesDTO> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(count);

        return TableListDTO.setPageData(pageInfo);
    }

    @Override
    public Integer add(TbClassesVO tbClassesVO) {
        TbClasses tbClasses = new TbClasses();
        BeanUtils.copyProperties(tbClassesVO, tbClasses);

        Integer insert = tbClassesMapper.insert(tbClasses);

        List<Integer> userIds = tbClassesVO.getUserIds();
        if (insert > 0 && !CollectionUtils.isEmpty(userIds)) {
            Integer id = tbClasses.getId();

            TbClassesUser tbClassesUser = null;
            for (Integer userId : userIds) {
                tbClassesUser = new TbClassesUser();
                tbClassesUser.setClassesId(id).setUserId(userId);
                tbClassesUserMapper.insert(tbClassesUser);
            }
        }

        Integer tbAttendanceRuleId = tbClassesVO.getTbAttendanceRules();
        if (tbAttendanceRuleId != null) {
            TbClassesRule tbClassesRule = new TbClassesRule();
            tbClassesRule.setClassesId(tbClasses.getId());
            tbClassesRule.setRuleId(tbAttendanceRuleId);
            tbClassesRuleMapper.insert(tbClassesRule);
        }

        return insert;
    }

    @Override
    public TbClassesDTO get(Integer id) {
        TbClasses tbClasses = tbClassesMapper.selectById(id);

        TbClassesDTO tbClassesDTO = new TbClassesDTO();
        if (tbClasses == null) {
            return tbClassesDTO;
        }

        BeanUtils.copyProperties(tbClasses, tbClassesDTO);
        LambdaQueryWrapper<TbClassesUser> queryWrapper = Wrappers.<TbClassesUser>lambdaQuery()
                .eq(true, TbClassesUser::getClassesId, id);
        List<TbClassesUser> tbClassesUsers = tbClassesUserMapper.selectList(queryWrapper);

        if (!CollectionUtils.isEmpty(tbClassesUsers)) {
            List<Integer> userIds = tbClassesUsers.stream()
                    .map(TbClassesUser::getUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(userIds)) {
                List<SysUser> sysUsers = sysUserMapper.selectBatchIds(userIds);
                tbClassesDTO.setSysUsers(sysUsers);
            }
        }

        LambdaQueryWrapper<TbClassesRule> ruleLambdaQueryWrapper = Wrappers.<TbClassesRule>lambdaQuery()
                .eq(true, TbClassesRule::getClassesId, id);
        TbClassesRule tbClassesRule = tbClassesRuleMapper.selectOne(ruleLambdaQueryWrapper);
        if (tbClassesRule != null) {
            Integer ruleId = tbClassesRule.getRuleId();
            tbClassesDTO.setTbAttendanceRules(ruleId);
        }

        return tbClassesDTO;
    }

    @Override
    public Integer update(TbClassesVO tbClassesVO) {
        TbClasses tbClasses = new TbClasses();
        BeanUtils.copyProperties(tbClassesVO, tbClasses);

        int update = tbClassesMapper.updateById(tbClasses);
        Integer id = tbClasses.getId();
        // 用户关联删除
        Map<String, Object> map = new HashMap<>();
        map.put("classes_id", id);
        tbClassesUserMapper.deleteByMap(map);
        tbClassesRuleMapper.deleteByMap(map);

        List<Integer> userIds = tbClassesVO.getUserIds();
        if (update > 0 && !CollectionUtils.isEmpty(userIds)) {
            TbClassesUser tbClassesUser = null;
            for (Integer userId : userIds) {
                tbClassesUser = new TbClassesUser();
                tbClassesUser.setClassesId(id).setUserId(userId);
                tbClassesUserMapper.insert(tbClassesUser);
            }
        }

        Integer tbAttendanceRuleId = tbClassesVO.getTbAttendanceRules();
        if (tbAttendanceRuleId != null) {
            TbClassesRule tbClassesRule = new TbClassesRule();
            tbClassesRule.setClassesId(tbClasses.getId());
            tbClassesRule.setRuleId(tbAttendanceRuleId);
            tbClassesRuleMapper.insert(tbClassesRule);
        }
        return update;
    }

    @Override
    public Integer deletes(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return 0;
        }
        int totalCount = tbClassesMapper.deleteBatchIds(ids);

        for (Integer id : ids) {
            Map<String, Object> map = new HashMap<>();
            map.put("classes_id", id);
            tbClassesUserMapper.deleteByMap(map);
        }

        return totalCount;
    }

    @Override
    public List<TbClassesPO> getListPO(TbClassesVO tbClassesVO) {
        List<TbClassesPO> tbClassesPOList = new ArrayList<>();

        LambdaQueryWrapper<TbClasses> wrapper = Wrappers.<TbClasses>lambdaQuery()
                .like(StringUtils.isNotBlank(tbClassesVO.getName()), TbClasses::getName, tbClassesVO.getName())
                .eq(StringUtils.isNotBlank(tbClassesVO.getType()), TbClasses::getType, tbClassesVO.getType())
                .in(!CollectionUtils.isEmpty(tbClassesVO.getIds()), TbClasses::getId, tbClassesVO.getIds());
        List<TbClasses> tbClassesList = tbClassesMapper.selectList(wrapper);

        if (!CollectionUtils.isEmpty(tbClassesList)) {
            TbClassesPO tbClassesPO = null;
            Integer index = 0;

            for (TbClasses tbClasses : tbClassesList) {
                index++;
                tbClassesPO = new TbClassesPO();

                String type = null;
                String attendanceTimeDescription = null;
                if ("1".equals(tbClasses.getType())) {
                    type = "固定班次";
                    attendanceTimeDescription = "上午" + getDateStr(tbClasses.getMorningWUp()) + "-" + getDateStr(tbClasses.getMorningWDown()) + "\n" +
                            "下午" + getDateStr(tbClasses.getAfternoonWUp()) + "-" + getDateStr(tbClasses.getAfternoonWDown());
                } else if ("2".equals(tbClasses.getType())) {
                    type = "弹性班次";
                    BigDecimal flexTime = Optional.ofNullable(tbClasses.getFlexTime()).orElse(BigDecimal.ZERO);

                    attendanceTimeDescription = "弹性工作" + flexTime.setScale(1, RoundingMode.HALF_UP).toString() + "小时";
                }
                BigDecimal workTime = Optional.ofNullable(tbClasses.getWorkTime()).orElse(BigDecimal.ZERO).setScale(1, RoundingMode.HALF_UP);

                tbClassesPO.setSno(index.toString())
                        .setName(tbClasses.getName())
                        .setType(type)
                        .setAttendanceTimeDescription(attendanceTimeDescription)
                        .setWorkTime(workTime.toPlainString());
                tbClassesPOList.add(tbClassesPO);
            }
        }
        return tbClassesPOList;
    }

    private String getDateStr(Date date) {
        if (date == null) {
            return StringUtils.EMPTY;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        return simpleDateFormat.format(date);
    }


}
